﻿using SqlSugar;
using Sunlight.Manage.Common.utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Sunlight.Manage.Common.BaseCore.Service
{
    /// <summary>
    /// 业务逻辑的基础公共的功能实现，通过继承来使用
    /// </summary>
    public abstract class BaseServiceImpl:BaseService
    {

        protected ISqlSugarClient _client;

        protected BaseServiceImpl(ISqlSugarClient client)
        {
            _client = client;
        }

        #region Query查询 
        /// <summary>
        /// 主键查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T Find<T>(int id) where T : class
        {
            return _client.Queryable<T>().InSingle(id);
        }

        /// <summary>
        /// 主键查询-异步版本
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<T> FindAsync<T>(int id) where T : class {
            return await _client.Queryable<T>().InSingleAsync(id);
        }

        /// <summary>
        /// 不应该暴露给上端使用者，尽量少用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        [Obsolete("尽量避免使用，using 带表达式目录树的代替")]
        public ISugarQueryable<T> Set<T>() where T : class {
            return _client.Queryable<T>();
        }

        /// <summary>
        /// 条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="funcWhere"></param>
        /// <returns></returns>
        public ISugarQueryable<T> Query<T>(Expression<Func<T, bool>> funcWhere) where T : class {
            return _client.Queryable<T>().Where(funcWhere);
        }

        public PagingData<T> QueryPage<T>(Expression<Func<T, bool>> funcWhere, int pageSize, int pageIndex,                     Expression<Func<T, object>> funcOrderby, bool isAsc = true) where T : class { 
            var list=_client.Queryable<T>();
            if (funcWhere != null) { 
                list=list.Where(funcWhere);
            }
            list = list.OrderByIF(true, funcOrderby, isAsc ? OrderByType.Asc : OrderByType.Desc);
            PagingData<T> result = new PagingData<T>()
            {
                DataList = list.ToPageList(pageIndex, pageSize),
                PageIndex = pageIndex,
                PageSize = pageSize,
                RecordCount = list.Count(),
            };
            return result;
        }
        #endregion

        #region  Add 添加
        /// <summary>
        /// 新增数据-同步版本
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public T Insert<T>(T t) where T : class, new() {
            return _client.Insertable(t).ExecuteReturnEntity();
        }

        /// <summary>
        /// 新增数据-异步版本
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<T> InsertAsync<T>(T t) where T : class, new() { 
            return await _client.Insertable(t).ExecuteReturnEntityAsync();
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tList"></param>
        /// <returns></returns>
        public async Task<bool> InsertList<T>(List<T> tList) where T : class, new() {
            return await _client.Insertable(tList.ToList()).ExecuteCommandIdentityIntoEntityAsync();
        }
        #endregion

        #region Update 更新
        /// <summary>
        /// 更新数据，即时Commit
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        public void Update<T>(T t) where T : class, new() {
            if (t == null) throw new Exception("t is null");
            _client.Updateable(t).ExecuteCommand();
        }

        /// <summary>
        /// 更新数据，异步版本
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task UpdateAsync<T>(T t) where T : class, new() {
            if (t == null) throw new Exception("t is null");
            await _client.Updateable(t).ExecuteCommandAsync();
        }

        /// <summary>
        /// 更新数据，即时Commit
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tList"></param>
        public void Update<T>(List<T> tList) where T : class, new() {
            _client.Updateable(tList).ExecuteCommand();
        }
        #endregion

        #region  Delete 删除
        /// <summary>
        /// 根据主键删除数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pId"></param>
        /// <returns></returns>
        public bool Delete<T>(object pId) where T : class, new() {
            T t = _client.Queryable<T>().InSingle(pId);
            return _client.Deleteable(t).ExecuteCommandHasChange();
        }

        /// <summary>
        /// 根据主键删除数据--异步版本
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pId"></param>
        /// <returns></returns>
        public async Task<bool> DeleteAsync<T>(object pId) where T : class, new() {
            T t = _client.Queryable<T>().InSingle(pId);
            return await _client.Deleteable(t).ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 删除数据，即时Commit
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public void Delete<T>(T t) where T : class, new() {
            _client.Deleteable(t).ExecuteCommand();
        }

        /// <summary>
        /// 删除数据，即时Commit
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tList"></param>
        public void Delete<T>(List<T> tList) where T : class, new() {
            _client.Deleteable(tList).ExecuteCommand();
        }
        #endregion

        #region Other
        /// <summary>
        /// 执行sql 返回集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <returns></returns>
        public ISugarQueryable<T> ExcuteQuery<T>(string sql) where T : class, new() {
            return _client.SqlQueryable<T>(sql);
        }

        public void Dispose() {
            if (_client != null)
            {
                _client.Dispose();
            }
        }
        #endregion

    }
}
